﻿/**
 * jQuery EasyUI 1.4
 * 
 * Copyright (c) 2009-2014 www.jeasyui.com. All rights reserved.
 * 
 * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt To use it
 * on other terms please contact us at info@jeasyui.com
 * 
 */
(function($) {
	function createCombo(target) {
		var combo = $.data(target, "combo");
		var opts = combo.options;
		if (!combo.panel) {
			if(opts.isBody){
				combo.panel = $("<div class=\"combo-panel\"></div>").appendTo("body");
			}else{
				var tablewrapCombo=$(target).closest("div.datagrid-top-wrap");
				if(tablewrapCombo.length<=0){
					$(target).data("tablewrapCombo",null);
					combo.panel = $("<div class=\"combo-panel\"></div>").appendTo($(target).wrap('<div class="easyui-top-wrap"></div>').parent());
				}else{
					$(target).data("tablewrapCombo",tablewrapCombo);
					combo.panel = $("<div class=\"combo-panel\"></div>").appendTo(tablewrapCombo);
				}
			}
			combo.panel.panel({
				minWidth : opts.panelMinWidth,
				maxWidth : opts.panelMaxWidth,
				minHeight : opts.panelMinHeight,
				maxHeight : opts.panelMaxHeight,
				doSize : false,
				closed : true,
				cls : "combo-p",
				style : {
					position : "absolute",
					zIndex : 10
				},
				onOpen : function() {
					var p = $(this).panel("panel");
					if ($.fn.menu) {
						p.css("z-index", $.fn.menu.defaults.zIndex++);
					} else {
						if ($.fn.window) {
							p.css("z-index", $.fn.window.defaults.zIndex++);
						}
					}
					$(this).panel("resize");
				},
				onBeforeClose : function() {
					comboClose(this);
				},
				onClose : function() {
					var combo = $.data(target, "combo");
					if (combo) {
						combo.options.onHidePanel.call(target);
					}
				}
			});
		}
		var icons = $.extend(true, [], opts.icons);
		if (opts.hasDownArrow) {
			icons.push({
				iconCls : "combo-arrow",
				handler : function(e) {
					comboArrow(e.data.target);
				}
			});
		}
		$(target).addClass("combo-f").textbox($.extend({}, opts, {
			icons : icons,
			onChange : function() {
			}
		}));
		$(target).attr("comboName", $(target).attr("textboxName"));
		combo.combo = $(target).next();
		combo.combo.addClass("combo");
	};
	function destroy(target) {
		var combo = $.data(target, "combo");
		combo.panel.panel("destroy");
		$(target).textbox("destroy");
	};
	function comboArrow(target) {
		var panel = $.data(target, "combo").panel;
		if (panel.is(":visible")) {
			hidePanel(target);
		} else {
			var p = $(target).closest("div.combo-panel");
			$("div.combo-panel:visible").not(panel).not(p).panel("close");
			$(target).combo("showPanel");
		}
		$(target).combo("textbox").focus();
	};
	function comboClose(target) {
		$(target).find(".combo-f").each(function() {
			var p = $(this).combo("panel");
			if (p.is(":visible")) {
				p.panel("close");
			}
		});
	};
	function bindEvent(target) {
		$(document).unbind(".combo").bind("mousedown.combo", function(e) {
			var p = $(e.target).closest("span.combo,div.combo-p,div.easyui-top-wrap,div.datagrid-top-wrap");
			if (p.length) {
				comboClose(p);
				return;
			}
			$("body>div.combo-p>div.combo-panel:visible").panel("close");
			$("div.easyui-top-wrap>div.combo-p>div.combo-panel:visible").panel("close");
			$("div.datagrid-top-wrap>div.combo-p>div.combo-panel:visible").panel("close");
		});
	};
	function clickEvent(e) {
		var target = e.data.target;
		var combo = $.data(target, "combo");
		var opts = combo.options;
		var panel = combo.panel;
		if (!opts.editable) {
			comboArrow(target);
		} else {
			var p = $(target).closest("div.combo-panel");
			$("div.combo-panel:visible").not(panel).not(p).panel("close");
		}
	};
	function keydownEvent(e) {
		var target = e.data.target;
		var t = $(target);
		var combo = t.data("combo");
		var opts = t.combo("options");
		switch (e.keyCode) {
		case 38:
			opts.keyHandler.up.call(target, e);
			break;
		case 40:
			opts.keyHandler.down.call(target, e);
			break;
		case 37:
			opts.keyHandler.left.call(target, e);
			break;
		case 39:
			opts.keyHandler.right.call(target, e);
			break;
		case 13:
			e.preventDefault();
			opts.keyHandler.enter.call(target, e);
			return false;
		case 9:
		case 27:
			hidePanel(target);
			break;
		default:
			if (opts.editable) {
				if (combo.timer) {
					clearTimeout(combo.timer);
				}
				combo.timer = setTimeout(function() {
					var q = t.combo("getText");
					if (combo.previousText != q) {
						combo.previousText = q;
						t.combo("showPanel");
						opts.keyHandler.query.call(target, q, e);
						t.combo("validate");
					}
				}, opts.delay);
			}
		}
	};
	function showPanel(target) {
		var combo = $.data(target, "combo");
		var combocb = combo.combo;
		var panel = combo.panel;
		var opts = $(target).combo("options");
		panel.panel("move", {
			left : _getLeft(),
			top : _getTop()
		});
		if (panel.panel("options").closed) {
			panel.panel("open").panel("resize", {
				width : (opts.panelWidth ? opts.panelWidth : combocb._outerWidth()),
				height : opts.panelHeight
			});
			opts.onShowPanel.call(target);
		}
		(function() {
			if (panel.is(":visible")) {
				panel.panel("move", {
					left : _getLeft(),
					top : _getTop()
				});
				setTimeout(arguments.callee, 200);
			}
		})();
		function _getLeft() {
			var tablewrapCombo=$(target).data("tablewrapCombo");
			if(tablewrapCombo){
				var tableLeft=tablewrapCombo.position().left;
				var panelWidth=panel._outerWidth();
				var combocbWidth=combocb._outerWidth();
				var left = combocb.position().left;
				var winWidth=$(window)._outerWidth()+$(document).scrollLeft();
				if (tableLeft+left+panelWidth +38> winWidth) {
					return winWidth - panelWidth - combocbWidth -38;
				}else{
					return left-combocbWidth;
				}
			}else{
				var left = combocb.position().left;
				if (opts.panelAlign == "right") {
					left += combocb._outerWidth() - panel._outerWidth();
				}
				if (left + panel._outerWidth() > $(window)._outerWidth() + $(document).scrollLeft()) {
					left = $(window)._outerWidth() + $(document).scrollLeft() - panel._outerWidth();
				}
				if (left < 0) {
					left = 0;
				}
				return left;
			}
		};
		function _getTop() {
			var tablewrapCombo=$(target).data("tablewrapCombo");
			if(tablewrapCombo){
				var top = 0;
				var tableTop=tablewrapCombo.position().top;
				var pTop = combocb.position().top;
				var combOutH= combocb._outerHeight();
				var winOutH=$(window)._outerHeight();
				var panelOutH= panel._outerHeight();
				var docSTop= $(document).scrollTop();
				if (tableTop + pTop + panelOutH +5 > winOutH+docSTop) {
					return top-panelOutH+pTop-5;
				}else{
					return top+pTop+combOutH+5;
				}
			}else{
				var comnoTop=combocb.position().top;
				var top = comnoTop + combocb._outerHeight();
				//如果是在表格中，
				if (top + panel._outerHeight() > $(window)._outerHeight() + $(document).scrollTop()) {
					top = combocb.offset().top - panel._outerHeight();
				}
				if (top < $(document).scrollTop()) {
					top = combocb.offset().top + combocb._outerHeight();
				}
				return top;
			}
			
		};
	};
	function hidePanel(target) {
		var panel = $.data(target, "combo").panel;
		panel.panel("close");
	};
	function clear(target) {
		var combo = $.data(target, "combo");
		var opts = combo.options;
		var combocb = combo.combo;
		$(target).textbox("clear");
		if (opts.multiple) {
			combocb.find(".textbox-value").remove();
		} else {
			combocb.find(".textbox-value").val("");
		}
	};
	function setText(target, val) {
		var combo = $.data(target, "combo");
		var text = $(target).textbox("getText");
		if (text != val) {
			$(target).textbox("setText", val);
			combo.previousText = val;
		}
	};
	function getValues(target) {
		var values = [];
		var combobc = $.data(target, "combo").combo;
		var combo = $.data(target, "combo");
		var opts = combo.options;
		combobc.find(".textbox-value").each(function() {
			var strVale=$(this).val();
			if(strVale){
				var staList=strVale.split(opts.separator);
				for(var i=0;i<staList.length;i++){
					values.push(staList[i]);
				}
			}else{
				values.push("");
			}
		});
		return values;
	};
	function setValues(target, arrayVals) {
		if (!$.isArray(arrayVals)) {
			arrayVals = [ arrayVals ];
		}
		var combo = $.data(target, "combo");
		var opts = combo.options;
		var combobc = combo.combo;
		var values = getValues(target);
		combobc.find(".textbox-value").remove();
		var textboxName = $(target).attr("textboxName") || "";
		for (var i = 0; i < arrayVals.length; i++) {
			var textboxValue = $("<input type=\"hidden\" class=\"textbox-value\">").appendTo(combobc);
			textboxValue.attr("name", textboxName);
			if (opts.disabled) {
				textboxValue.attr("disabled", "disabled");
			}
			textboxValue.val(arrayVals[i]);
		}
		var _3d = (function() {
			if (values.length != arrayVals.length) {
				return true;
			}
			var a1 = $.extend(true, [], values);
			var a2 = $.extend(true, [], arrayVals);
			a1.sort();
			a2.sort();
			for (var i = 0; i < a1.length; i++) {
				if (a1[i] != a2[i]) {
					return true;
				}
			}
			return false;
		})();
		if (_3d) {
			if (opts.multiple) {
				opts.onChange.call(target, arrayVals, values);
			} else {
				opts.onChange.call(target, arrayVals[0], values[0]);
			}
		}
	};
	function getValue(target) {
		var values = getValues(target);
		return values[0];
	};
	function setValue(target, values) {
		setValues(target, [ values ]);
	};
	
	function setValue(target, values) {
		setValues(target, [ values ]);
	};
	function initValue(target) {
		var opts = $.data(target, "combo").options;
		var changeEvent = opts.onChange;
		opts.onChange = function() {};
		if (opts.multiple) {
			setValues(target, opts.value ? opts.value : []);
		} else {
			setValue(target, opts.value);
		}
		opts.onChange = changeEvent;
	};
	$.fn.combo = function(options, param) {
		if (typeof options == "string") {
			var method = $.fn.combo.methods[options];
			if (method) {
				return method(this, param);
			} else {
				return this.textbox(options, param);
			}
		}
		options = options || {};
		return this.each(function() {
			var combo = $.data(this, "combo");
			if (combo) {
				$.extend(combo.options, options);
				if (options.value != undefined) {
					combo.options.originalValue = options.value;
				}
			} else {
				combo = $.data(this, "combo", {
					options : $.extend({}, $.fn.combo.defaults, $.fn.combo.parseOptions(this), options),
					previousText : ""
				});
				combo.options.originalValue = combo.options.value;
			}
			createCombo(this);
			bindEvent(this);
			initValue(this);
		});
	};
	$.fn.combo.methods = {
		options : function(jq) {
			var opts = jq.textbox("options");
			return $.extend($.data(jq[0], "combo").options, {
				width : opts.width,
				height : opts.height,
				disabled : opts.disabled,
				readonly : opts.readonly
			});
		},
		panel : function(jq) {
			return $.data(jq[0], "combo").panel;
		},
		destroy : function(jq) {
			return jq.each(function() {
				destroy(this);
			});
		},
		showPanel : function(jq) {
			return jq.each(function() {
				showPanel(this);
			});
		},
		hidePanel : function(jq) {
			return jq.each(function() {
				hidePanel(this);
			});
		},
		clear : function(jq) {
			return jq.each(function() {
				clear(this);
			});
		},
		reset : function(jq) {
			return jq.each(function() {
				var _4d = $.data(this, "combo").options;
				if (_4d.multiple) {
					$(this).combo("setValues", _4d.originalValue);
				} else {
					$(this).combo("setValue", _4d.originalValue);
				}
			});
		},
		setText : function(jq, _4e) {
			return jq.each(function() {
				setText(this, _4e);
			});
		},
		getValues : function(jq) {
			return getValues(jq[0]);
		},
		setValues : function(jq, _4f) {
			return jq.each(function() {
				setValues(this, _4f);
			});
		},
		getValue : function(jq) {
			return getValue(jq[0]);
		},
		setValue : function(jq, _50) {
			return jq.each(function() {
				setValue(this, _50);
			});
		},
		setValue : function(jq, _50) {
			return jq.each(function() {
				setValue(this, _50);
			});
		}
	};
	$.fn.combo.parseOptions = function(target) {
		var t = $(target);
		return $.extend({}, $.fn.textbox.parseOptions(target), $.parser
				.parseOptions(target, [ "separator", "panelAlign", {
					panelWidth : "number",
					hasDownArrow : "boolean",
					delay : "number",
					selectOnNavigation : "boolean"
				}, {
					panelMinWidth : "number",
					panelMaxWidth : "number",
					panelMinHeight : "number",
					panelMaxHeight : "number"
				} ]), {
			panelHeight : (t.attr("panelHeight") == "auto" ? "auto"
					: parseInt(t.attr("panelHeight")) || undefined),
			multiple : (t.attr("multiple") ? true : undefined)
		});
	};
	$.fn.combo.defaults = $.extend({}, $.fn.textbox.defaults, {
		inputEvents : {
			click : clickEvent,
			keydown : keydownEvent,
			paste : keydownEvent,
			drop : keydownEvent
		},
		isBody:false,
		selectObject:null,
		panelWidth : null,
		panelHeight : 200,
		panelMinWidth : null,
		panelMaxWidth : null,
		panelMinHeight : null,
		panelMaxHeight : null,
		panelAlign : "left",
		multiple : false,
		selectOnNavigation : true,
		separator : ",",
		hasDownArrow : true,
		delay : 200,
		regChars:[],
		keyHandler : {
			up : function(e) {
			},
			down : function(e) {
			},
			left : function(e) {
			},
			right : function(e) {
			},
			enter : function(e) {
			},
			query : function(q, e) {
			}
		},
		onShowPanel : function() {
		},
		onHidePanel : function() {
		},
		onChange : function(_52, _53) {
		}
	});
})(jQuery);
